<?php
/**
 * | 节程 [ 节程赋能开发者，助力企业发展 ]
 * +----------------------------------------------------------------------
 *  | Copyright (c) 2020~2029 温州惊蛰网络科技有限公司 All rights reserved.
 * +----------------------------------------------------------------------
 *  | Licensed 节程并不是自由软件，未经许可不能去掉节程相关版权
 * +----------------------------------------------------------------------
 */
declare (strict_types=1);

namespace app\shop_admin\service;

use app\index\model\MallBase;
use app\index\model\OrderCommodityAttach;
use app\index\service\InventoryService;
use app\shop_admin\model\AfterOrderCommodity;
use app\shop_admin\model\AgentBillTemporary;
use app\shop_admin\model\Commodity;
use app\shop_admin\model\Coupon;
use app\shop_admin\model\Distribution;
use app\shop_admin\model\OrderAfter;
use app\shop_admin\model\OrderMoneyChange;
use app\shop_admin\model\Sku;
use app\shop_admin\model\User;
use app\shop_admin\model\UserCash;
use app\shop_admin\model\UserCoupon;
use app\shop_admin\model\Order;
use app\shop_admin\model\OrderCommodity;
use app\shop_admin\model\OrderFreight;
use app\shop_admin\model\UserWx;
use app\shop_admin\model\SkuInventory;
use app\shop_admin\validate\OrderValidate;
use app\utils\SendMsg;
use app\utils\TrimData;
use PhpOffice\PhpSpreadsheet\Exception;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\db\Query;
use think\exception\HttpException;
use think\facade\Db;
use think\facade\Request;
use app\utils\Dada;
use app\utils\DaDaSdk;
use app\shop_admin\model\Dada as Da;
use app\shop_admin\model\RechargeRecord;
use app\shop_admin\model\GroupCommodity;
use app\index\model\Collage;
use app\index\model\SeckillCommodity;

class OrderService
{
    /**
     * 查询列表
     * @param int $page
     * @param int $size
     * @param array $data
     * @return array
     */
    public function orderList(array $data, int $page = 1, int $size = 10)
    {
        $res = Order::where($this->bulidWhere($data))
            ->alias('a');
        if (!empty($data['is_print_list']))
            $res = $res->where('a.status','NOT IN',[1,12]);
        $res = $res
            ->join('user u', 'a.user_id=u.id', 'LEFT')
            ->join('order_commodity o', 'a.id=o.order_id', 'LEFT')
            ->join('order_freight r', 'a.id=r.order_id', 'LEFT')
            ->join('commodity c', 'o.commodity_id=c.id', 'LEFT')
            ->field('
           a.order_no,a.pay_no,a.create_time,a.id,a.status,round((a.money- IFNULL(a.discount,0) - IFNULL(a.discount_amount,0) + any_value(IFNULL(r.freight,0))),2) as money,a.address,
           a.pay_id,any_value(IFNULL(r.freight,0)) as freight,a.after_status,a.discount_amount,a.remake,a.is_evaluate,
           a.order_type,a.deliver_type,a.discount,a.after_type,a.mall_id,a.source,a.type,a.order_from,o.collage_id,
           u.nickname,u.picurl,IFNULL(a.consignee,"暂无") as user_real_name, IFNULL(a.iphone,"暂无") as user_mobile,a.unified_order_no,a.has_attach,a.distribution_fee,discount_level_money
           ')
            ->with(['orderCommoditys', 'orderCommoditys.orderAfter'])
            ->group('a.id')
            ->order('a.id desc')
            ->paginate(['page' => $page, 'list_rows' => $size]);

        foreach ($res as $k => $v) {
            if ($v['has_attach'] == 1) {
                $res[$k]['attach'] = Db::name("order_commodity_attach")->where('order_id', $v['id'])->select();
            }

            if ($v['collage_id'] != 0 && in_array($v['status'], ['待支付','待发货','已发货'])) {
                $collage = Db::name('collage')->find($v['collage_id'])['status'];
                $status = [1 => "13", 2 => "14", 11 => "15"];
                if ($res[$k]['status'] == "已发货" && $collage == 2) {
                    $res[$k]['status'] = 3;
                } else {
                    $res[$k]['status'] = $status[$collage];
                }
                $res[$k]['group_status'] = $collage;
            }
            $res[$k]['dada'] = Db::name('dada')
                ->where('order_id', $v['id'])
                ->where('order_status', 'in', '1,2,3,4,8,9,10,100')
                ->select();
            $res[$k]['y_money'] = 0;
            foreach ($v['orderCommoditys'] as $kcom => $vcom) {
                if (empty($vcom['sku_id'])) {
                    $y_money = Commodity::find($kcom['commodity_id'])['sell_price'] * $vcom['count'];
                } else {
                    $y_money =  SkuInventory::find($kcom['sku_id'])['sell_price'] * $vcom['count'];
                }
                $res[$k]['orderCommoditys'][$kcom]['y_money'] = $y_money;
                $res[$k]['y_money'] += $y_money;
            }
        }

        return [HTTP_SUCCESS, $res];
    }

    /**
     * 删除一条数据
     * @param int $id
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     * @throws \think\Exception
     */
    public function orderDel(int $id)
    {
        $data = [
            'status' => 12,
            'settlement' => 3
        ];
        $find = Order::where('status', 12)->find($id);
        if ($find) throw new  \think\Exception('该订单已删除,不能重复删除', HTTP_INVALID);
        $up = Order::update($data, ['id' => $id]);
        $orders = OrderCommodity::where('order_id', $id)
            ->alias('a')
            ->join('commodity c', 'a.commodity_id = c.id', 'LEFT')
            ->join('sku_inventory s', 'a.sku_id = s.sku_id', 'LEFT')
            ->field('a.commodity_id,a.count,( CASE WHEN c.has_sku = 1 THEN s.sell_price ELSE c.sell_price END) as price ,a.sku_id')
            ->select();
        AgentBillTemporary::orderDel($id);
        foreach ($orders as $v) {
            $inventory = new InventoryService($v['commodity_id']);
            $inventory->backInventory($v['count'], $v['price'], $v['sku_id']);
        }
        //退还优惠券
        //$this->return_coupon($id);
        return [HTTP_CREATED, "成功!"];
    }

    /**
     * @param int $id
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     * @throws \think\Exception
     */
    public function orderClose(int $id)
    {
        $find = Order::find($id);
        if (!$find){
            throw new \think\Exception('找不到该订单', HTTP_INVALID);
        }

        if ($find->status !="待支付") throw new \think\Exception('该订单不是待支付状态,不能关闭', HTTP_INVALID);
        $up = Order::update(['status' => 12, 'settlement' => 3], ['id' => $id]);
        global $m_id;
        $m_id=$find->mall_id;

        $orders = OrderCommodity::where('order_id', $id)
            ->alias('a')
            ->join('commodity c', 'a.commodity_id = c.id', 'LEFT')
            ->join('sku_inventory s', 'a.sku_id = s.sku_id', 'LEFT')
            ->field('a.commodity_id,a.mall_id,a.count,( CASE WHEN c.has_sku = 1 THEN s.sell_price ELSE c.sell_price END) as price ,a.sku_id, a.sc_id')
            ->select();

        foreach ($orders as $v) {
            if ($find['order_from'] == 2) {
                SeckillCommodity::incStock($v['sc_id'], $v['count'], $v['sku_id']);
            }
            $c = Commodity::find($v['commodity_id']);
            if (!empty($c)) {
                $inventory = new InventoryService($v['commodity_id']);
                $inventory->backInventory($v['count'], $v['price'], $v['sku_id']);
            }
        }
        return [HTTP_CREATED, $up];
    }

    /**
     * 保存数据
     * @param array $data
     * @return array
     */
    public function save(array $data)
    {
        $res = Order::update($data);
        return [HTTP_SUCCESS, $res];
    }

    /**
     * 导出数据
     * @param array $data
     */
    public function export(array $data)
    {
        try {
            $order = Order::alias('a')
                ->where($this->bulidWhere($data))
                ->join('merchant m', 'a.merchant_id=m.id', 'LEFT')
                ->join('user u', 'a.user_id=u.id', 'LEFT')
                ->join('order_freight o', 'a.id=o.order_id', 'LEFT')
                ->join('user_address s', 'a.user_address_id=s.id', 'LEFT')
                ->with(['orderCommodity' => function ($query) {
                    $query->alias('a')
                        ->join('commodity c', 'a.commodity_id = c.id', 'LEFT')
                        ->join('sku s', 'a.sku_id = s.id', 'LEFT')
                        ->field('c.name as cname,a.count,a.price,s.pvs_value,a.express_company,a.logistics_no,a.order_id');
                }])
                ->field('a.id,a.order_no,a.money,o.freight,a.pay_no,a.pay_time,m.name,u.nickname,s.address,
                         a.consignee,a.after_status,a.order_type,a.create_time,a.remake')
                ->select()
                ->toArray();

            $newdata = [];
            $array = [0 => '未知', 1 => '快递', 2 => '自提', 3 => '同城配送'];
            $state_arr = [0 => '未知', 1 => "维权中", 2 => "维权完成", 3 => "未维权", 4 => '维权驳回'];
            foreach ($order as $k => $value) {
                $type = $array[$value['order_type']];
                $state = $state_arr[$value['after_status']];
                unset($value['order_type']);
                unset($value['after_status']);
                foreach ($value['orderCommodity'] as $kk => $v) {
                    unset($value['orderCommodity'][$kk]['order_id']);
                }
                $value['after_status'] = $state;
                $value['order_type'] = $type;
                $newdata[] = $value;
            }
            $headArr = [
                'ID', '订单流水号', '金额', '运费', '支付流水号',
                '付款时间', '商户名称', '下单客户', '送货地址',
                '收货人', '下单时间', '备注', '维权状态', '快递类型',
                '商品名称', '数量', '单价', 'sku', '快递公司', '快递单号'
            ];
            $excel = new ExcelService();
            $excel->excelExport('订单', '订单列表', $headArr, $newdata);
        } catch (Exception $e) {
            throw new \PDOException($e->getMessage(), HTTP_INVALID);
        }
    }

    /**
     * 读取一条订单数据
     * @param int $id 订单ID
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     * @throws \think\Exception
     */
    public function orderInfo(int $id)
    {
        $res = Order::with(['orderCommoditys', 'freight', 'user'])
            ->field('status,remake,order_no,pay_id,pay_no,create_time,id,user_id,address,consignee,iphone,money,remake,order_type,discount,discount_amount,pay_no,unified_order_no,distribution_fee,has_attach,discount_level_money,delivery_time,order_from')
            ->find($id);
        if ($res['order_from'] == 1 && in_array($res['status'], ['待支付','待发货','已发货'])) {
            $collage = Db::name('collage')->find($res['orderCommoditys'][0]['collage_id'])['status'];
            $status = [1 => "13", 2 => "14", 11 => "15"];
            if ($res['status'] == "已发货" && $collage == 2) {
                $res['status'] = 3;
            } else {
                $res['status'] = $status[$collage];
            }
            $res['group_status'] = $collage;
        }
        if ($res['has_attach'] == 1) {
            $res['attach'] = Db::name("order_commodity_attach")->where('order_id', $id)->select();
        }
        $res['dada'] = Db::name('dada')
            ->where('order_id', $id)
            ->where('order_status', 'in', '1,2,3,4,8,9,10,100')
            ->select();

        return [HTTP_SUCCESS, $res];
    }

    /**
     * 订单发货
     * @param array $data
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function saveOrderStatus(array $data)
    {
        $validate = new OrderValidate();
        if (!$validate->scene('distribution')->check($data)) {
            return [HTTP_INVALID, $validate->getError()];
        }
        $data['deliver_time'] = date("Y-m-d H:i:s", time());
        if ($data['type'] == 1) {
            $after_status = Order::where('id', $data['id'])->value('after_status');
            if (in_array($after_status, [1, 2])) throw new HttpException(HTTP_INVALID, "订单维权中不允许整单发货");
            $id = $data['id'];
            $type = $data['type'];
            unset($data['type'], $data['id']);
            $res = Order::where(['id' => $id])->update(['status' => 3, "deliver_type" => $type]);
            $data['status'] = 3;
            (new Order())->orderCommodity()->where('order_id', $id)->update($data);
            $this->sendMsg($id, "订单发货通知");
            return [HTTP_SUCCESS, $res];
        }
        $js = is_array($data['cids']) ? $data['cids'] : json_decode($data['cids'], true);
        $cids = array_column($js, 'order_commodity_id');
        $status = OrderCommodity::where('id', 'in', $cids)
            ->select()
            ->toArray();
        $id = $data['id'];
        $type = $data['type'];
        Order::where(['id' => $id])->update(["deliver_type" => $type]);
        unset($data['id'], $data['type'], $data['status'], $data['cids']);
        $data['status'] = 3;
        foreach ($status as $v) {
            if (in_array($v['after_status'], [1, 2])) throw new HttpException(HTTP_INVALID, "维权订单不允许发货");
            OrderCommodity::where('id', $v['id'])->update($data);
        }
        $this->sendMsg($id, "订单发货通知");
        $this->upOrderState($id);
        return [HTTP_SUCCESS, "成功!"];
    }

    /**
     * 同城配送发货
     * @param $oid int 订单id
     * @param $type int 配送对象 1：自身 2：第三方
     * @param $third int 第三方 1：达达 2：美团
     */
    public function localDelivery($oid, $type, $third, $dada_data)
    {
        $order = Order::find($oid);
        switch ($type) {
            case 1:
                if (in_array($order['after_status'], [1])) {
                    throw new HttpException(HTTP_INVALID, "订单维权中不允许整单发货");
                }
                $res = Order::where(['id' => $oid])->update(['status' => 3, "deliver_type" => 1]);
                $data['status'] = 3;
                $data['deliver_time'] = date("Y-m-d H:i:s", time());
                (new Order())->orderCommodity()
                    ->where('order_id', $oid)
                    ->where('status', 2)
                    ->update($data);
                $this->sendMsg($oid, "订单发货通知");
                return [HTTP_SUCCESS, $res];
                break;
            case 2:
                $commodity = OrderCommodity::field("store_id")->where('order_id', $oid)->find();
                $dis = Distribution::where('store_id', $commodity['store_id'])->find();
                switch ($third) {
                    case 1:
                        $config = json_decode($dis['config']);
                        $appkey = $config[0]->app_key;
                        $appsec = $config[0]->app_secret;

                        $source_id = $config[0]->app_source_id;
                        $shop_no = $config[0]->app_store_number;

//                        $source_id = '370221725';  //商户编号
//                        $shop_no = '38fa84c00ac44efb'; //门店编号

                        $dada = new DaDaSdk($appkey,$appsec,$source_id,$shop_no);
                        $data['shop_no'] = $shop_no;
                        $data['origin_id'] = $order['order_no'];
                        $data['city_code'] = $dada_data['city_code']; // 订单所在城市的code
                        $data['cargo_price'] = $order['money'];
                        $data['is_prepay'] = $dada_data['is_prepay']; // 是否需要垫付 1:是 0:否 (垫付订单金额，非运费)
                        $data['receiver_name'] = $order['consignee'];
                        $data['receiver_address'] = $order['address'];
                        $data['receiver_phone'] = $order['iphone'];

                        $data['callback'] = request()->server("REQUEST_SCHEME") . '://' .$_SERVER['HTTP_HOST']."/shop/dada_call_back";
                        $data['cargo_weight'] = $dada_data['cargo_weight']; // 重量

                        $delive = $dada->queryDeliverFee($data);

                        if ($delive['status'] == "success") {
                            $res = $delive['result'];
                            $dd = Da::insertGetId([
                                'distance' => $res['distance'],
                                'fee' => $res['fee'],
                                'deliver_fee' => $res['deliverFee'],
                                'client_id' => $res['deliveryNo'],
                                'insurance_fee' => $res['insuranceFee'],
                                'tips' => $res['tips'],

                                'order_id' => $order['id'],
                                'mall_id' => $order['mall_id'],
                                'create_time' => date('Y-m-d H:i:s', time())
                            ]);
                            $dda = Da::find($dd);
                            $dda['status'] = 1;
                            return [HTTP_SUCCESS, $dda];
                        } else {

                            if (isset($delive['result'])) {
                                $res = $delive['result'];
                                $res['msg'] = $delive['msg'];
                            } else {
                                $res['msg'] = $delive['msg'];
                            }

                            return [HTTP_INVALID, $res];
                        }

                        break;
                    case 2:
                        return [HTTP_INVALID, "正在开发中，请配置美团配送！"];
                        break;
                }
                break;
        }
        return [HTTP_SUCCESS, $order];
    }


    /**
     * 获取同城配送的设置
     * @param $oid int 订单id
     */
    public function getDistribution(int $oid)
    {
        $order = Order::find($oid);
        if ($order['order_type'] != 3) {
            throw new  \think\Exception('订单不是同城配送！', HTTP_INVALID);
        }
        $commodity = OrderCommodity::where('order_id', $oid)->select()->toArray();
        $distribution = Distribution::field('type,third_party')->where('store_id', $commodity[0]['store_id'])->find()->toArray();
        $types = explode(',', $distribution['type']);
        // type 1-商家配送 2-第三方配送
        // third_party 第三方配送，1-美团配送 2-达达配送
        foreach ($types as $key => $value) {
            if ($value == 2) {
                $types[$key] = ['third' => $distribution['third_party']];
            }
        }
        return [HTTP_SUCCESS, $types];
    }

    /**
     * 修改订单收货信息
     * @param array $data
     * @return array
     */
    public function saveConsignee(array $data)
    {
        $id = $data['id'];
        unset($data['id']);
        $res = Order::update($data, ['id' => $id]);
        return [HTTP_SUCCESS, $res];
    }

    /**
     * 修改订单收货信息
     * @param array $data
     * @return array
     */
    public function changeMoney(array $data)
    {
        global $user;

        $id = $data['id'];
        $type=$data['type'] ?? '';

        if($user->affiliation == 'saas') {
            $admin = Db::name('saas_admin')->where('id', $user->id)->find();
        }else if($user->affiliation == 'suser') {
            $admin = Db::name('saas_user')->where('id', $user->id)->find();
        }else{
            $admin = \app\madmin\model\Admin::where('status', 1)->where('id', $user->id)->find()->toArray();
        }
        if (!$admin || hash('sha256', $data['password']) != $admin['password'])
            return [HTTP_NOTACCEPT, "密码错误"];

        $order= Order::where(['status'=>1,'id'=>$id])->find();
        if (!$order){
            return [HTTP_NOTACCEPT, "订单不存在"];
        }
        if ($data['money']<=0){
            return [HTTP_NOTACCEPT, "调整的金额不能为0或小于0"];
        }
        $change_data=[
            'mall_id'=>$order->mall_id,
            'order_id'=>$order->id,
            'order_no'=>$order->order_no,
            'money'=>$data['money'] ,
            'old_money'=>$order->money,
            'admin_id'=>$user->id ?? 0,
            'time'=>date('Y-m-d H:i:s',time()),
            'merchant_id'=>$order->merchant_id,
            'type'=>$type
        ];
        if (is_numeric($type) && $type==0){
            $order->money=bcadd($order->money,$data['money']);
        }elseif(is_numeric($type) && $type==1){
            if ($order->money <= $data['money']){
                return [HTTP_NOTACCEPT, "调整后的金额不能小于或等于0"];
            }else{
                $order->money=bcsub($order->money,$data['money']);
            }
        }else{
            return [HTTP_NOTACCEPT, "请求参数异常"];
        }
        $change_data['new_money']=$order->money;
        $order->save();
        OrderMoneyChange::create($change_data);

        return [HTTP_SUCCESS, $order];
    }
    public function changeMoneyList(array $data,int $page = 1, int $size = 10){
        $admin = OrderMoneyChange::field('id,order_no,money,old_money,new_money,type,time');
        $list = $admin->where($data)->paginate(['page' => $page, 'list_rows' => $size]);
        return [HTTP_SUCCESS, $list];
    }

    /**
     * @param int $id
     * @param int $state
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     * @throws \think\Exception
     */
    public function modifyOrderState(int $id, int $state)
    {
        $order = Order::with("orderCommodity")->find($id)->toArray();
        if ($order['order_from'] == 1) {
            $oc_id = $order['orderCommodity'][0]['id'];
            Collage::createCollage($oc_id, $order['user_id']);
        }
        //订单状态: 1-待支付 2-待发货 3-已发货 4-已完结 5-已评价   6-删除 7-部分发货 8-已收货 9-部分收货 10-维权中 11-维权完成 12-已关闭
        $up = Order::where('id', $id)->update(['status' => $state, 'pay_id' => 4]);
        //订单状态: 1-待支付 2-待发货 3-已发货 4-已完结 5-已评价   6-删除 7-已收货 8-维权中 9-已维权 10-维权驳回 11-已关闭
        OrderCommodity::where('order_id', $id)->update(['status' => $state]);
        if ($state == 2) {
            global $user;
            if(\app\utils\Addons::check($user->mall_id,10)){
                $receipt = new ReceiptsService();
                $receipt->implementation_plan([$id],'pay');
            }
            Order::update(['settlement' => 1], ['id' => $id]);
            try {
                $this->sendMsg($id, "订单支付通知");
            } catch (\Exception $e) {
                
            }
        }
        return [HTTP_SUCCESS, $up];
    }


    /**
     * @param int $id
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function storeList(int $id)
    {
        $res = OrderCommodity::where('order_id', $id)->field('commodity_id,sku_id')->select()->toArray();
        $arr = [];
        foreach ($res as $k => $v) {
            $sku = $v['sku_id'] ?? null;
            $arr[$k]['commodity_id'] = $v['commodity_id'];
        }
        return [HTTP_SUCCESS, $arr];
    }

    /**取消发货
     * @param array $data
     * @param array $js
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function cancelOrder(array $data, array $js)
    {
        //$find = Db::name("order")->where('id', $data['order_id'])->find();
        $this->return_coupon($data['order_id']);
        //订单状态: 1-待支付 2-待发货 3-已发货 4-已完结 5-已评价   6-删除 7-部分发货 8-已收货 9-部分收货  12-已关闭
        $ocs = OrderCommodity::where(['order_id' => $data['order_id'], 'status' => 3])->field('commodity_id,sku_id,id')->select()->toArray();
        $flag = false;
        foreach ($js as $v) {
            $order_status = OrderCommodity::where(["id" => $v['cid']])->find();
            if (in_array($order_status['after_status'], [1, 2, 4])) throw new HttpException(HTTP_INVALID, '商品目前状态不能取消发货');
            if (!in_array($order_status->getData('status'), [3])) throw new HttpException(HTTP_INVALID, '商品目前状态不能取消发货');
            OrderCommodity::where(['id' => $v['cid']])->update(['status' => 2, 'logistics_no' => null, "express_company" => null]);
            foreach ($ocs as $kk => $vv) {
                if (($v['cid'] == $vv['id']) && ($v['sku_id'] == $vv['sku_id'])) unset($ocs[$kk]);
            }
            if (count($ocs) == 0) $flag = true;
        }
        if ($flag) Order::update(['deliver_type' => null], ['id' => $data['order_id']]);
        $this->upOrderState($data['order_id']);
        return [HTTP_SUCCESS, "成功!"];
    }

    private function bulidWhere(array $data)
    {
        global $user;
        $where = [];
        $arr = [];
        $res = [];
        $where[] = ['a.mall_id', '=', $user->mall_id];
        $where[] = ['a.merchant_id', '=', $user['merchant_id']];
        if (array_key_exists('order_type', $data))
            $where[] = ['a.order_type', '=', $data['order_type']];
        if ($data['status'] == 2 && !array_key_exists('order_type', $data)) $where[] = ['a.order_type', '=', 1];
        empty($data['status']) && $where[] = ['a.status', '<>', 6];
        !empty($data['order_no']) && $where[] = ['a.order_no', '=', $data['order_no']];
        !empty($data['pay_type']) && $where[] = ['a.pay_id', '=', $data['pay_type']];
        !empty($data['status']) && $where[] = ['a.status', '=', $data['status']];
        if (isset($data['order_from']) && $data['order_from'] != "") {
            $where[] = ['a.order_from', '=', $data['order_from']];
        }
        if ((array_key_exists('type', $data) && !empty($data['type']) && (array_key_exists('keyword', $data) && !empty(trim($data['keyword']))))) $res = $this->setType($data['type'], $data['keyword']);
        if (array_key_exists('start_time', $data) && array_key_exists('end_time', $data))
            $arr = $this->setTime($data['start_time'], $data['end_time']);
        return array_merge($where, $arr, $res);
    }

    private function setType($type, $value)
    {
        $where = [];
        switch ($type) {
            // 1 会员ID 2 会员信息 3 收件人信息 4地址信息 5 商品名称 6 商品编号 7 订单编号
            case 1:
                $where[] = ['a.user_id', '=', $value];
                break;
            case 2:
                $where[] = ['u.nickname|u.name', '=', $value];
                break;
            case 3:
                $where[] = ['a.consignee', '=', trim($value)];
                break;
            case 4:
                $where[] = ['a.address', 'like', '%' . trim($value) . '%'];
                break;
            case 5:
                $where[] = ['c.name', 'like', trim($value) . '%'];
                break;
            case 6:
                $where[] = ['c.id', '=', trim($value)];
                break;
            case 7:
                $where[] = ['a.order_no', '=', trim($value)];
                break;
        }

        return $where;
    }

    private function setTime($start_time, $end_time)
    {
        $arr = [];
        if (!empty($start_time) && !empty($end_time))
            $arr[] = ['a.create_time', 'between', [$start_time, $end_time]];
        elseif (!empty($start_time) && empty($end_time))
            $arr[] = ['a.create_time', 'between', [$start_time, date('Y-m-d H:i:s', time())]];
        elseif (empty($start_time) && !empty($end_time))
            $arr[] = ['a.create_time', 'between', [date('Y-m-d H:i:s', strtotime($end_time) - 60), $end_time]];
        return $arr;
    }

    /**
     * @param string $oId
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    private function upOrderState($oId)
    {
        upOrderState($oId);
    }

    /** 退款
     * @param int $oId
     * @return array
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws \think\Exception
     * @throws \think\db\exception\DbException
     */
    public function drawback(int $oId)
    {
        $find = Order::with('orderCommodity')->find($oId);
        $data = $find->toArray();

        foreach ($data['orderCommodity'] as $k => $v) {
            if (!in_array($v['status'], ['待发货'])) throw new HttpException(HTTP_INVALID, '该订单-子订单状态不是待发货');
        }
        if (in_array($find['after_status'], [1, 2])) throw new HttpException(HTTP_INVALID, '该订单为维权订单,不能退款!');
        $freight = OrderFreight::where('order_id', $oId)->value('freight');
        $money = bcsub($find['money'], strval(($find['discount'] + $find['discount_amount'])), 2);
        $money += $freight;
        OrderCommodity::where('order_id', $oId)->update(['status' => 11, 'type' => 3]);
        $this->upOrderState($oId);
        if ($find->getData('pay_id') != 4) {
            $pay = new PaymentService();
            $pay->refund($oId, ['refund' => $money]);
            $this->return_coupon($oId);
            Db::name('order_agent_profit')->where('order_id', $oId)->delete();
            Db::name('agent_bill_temporary')->where('order_id', $oId)->delete();
            if ($find->getData('pay_id') == 1) {
                $total = UserCash::where('user_id', $find->user_id)->value('total');
                RechargeRecord::create([
                    'user_id' => $find['user_id'],
                    'mall_id' => $find['mall_id'],
                    'base_in' => 'admin',
                    'source_type' => 6,
                    'source' => '退款',
                    'is_online' => 1,
                    'type' => 0,
                    'card' => '{}',
                    'money' => $money,
                    'service_charge' => 0,
                    'remark' => '退款' . $money,
                    'trade' => $find['order_no'],
                    'pay_no' => '',
                    'status' => 1,
                    'new_cash' => $total,
                    'old_cash' => $total - $money
                ]);
            }
        }
        // 秒杀
        if ($find['order_from'] == 2) {
            $oc = $data['orderCommodity'][0];
            SeckillCommodity::incStock($oc['sc_id'], $oc['count'], $oc['sku_id']);
        }
        Order::update(['settlement' => 3], ['id' => $oId]);
        $this->sendMsg($oId, "订单手动退款通知");
        return [HTTP_SUCCESS, '退款成功!'];
    }

    /** 退还优惠券
     * @param int $oId
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    private function return_coupon(int $oId)
    {

        $find = Order::find($oId);
        $user_coupon = UserCoupon::where('unified_order_no', $find['order_no'])->find();
        if (empty($user_coupon)) return;
        $coupon = Coupon::where('id', $user_coupon['coupon_id'])->find();
        $flag = true;
        $ids = OrderCommodity::where('order_id', $oId)->field('id')->select()->toArray();
        $id_arr = array_column($ids, 'id');
        $after_ids = OrderAfter::where('order_id', $oId)->field('id')->select()->toArray();
        $afters = array_column($after_ids, 'id');
        $ocids = AfterOrderCommodity::where('order_after_id', 'in', $afters)->field('ocid')->select()->toArray();
        $ocids_arr = array_column($ocids, 'ocid');
        $tally = count(array_diff($id_arr, $ocids_arr));

        //1-待支付 2-待发货 3-已发货 4-已完结 5-已评价   6-删除 7-部分发货 8-已收货 9-部分收货 10-维权中 11-维权完成 12-已关闭
        if (!in_array($find->getData('status'), [1, 2, 3, 7, 9]) || $tally > 1) {
            return;
        }
        if (!empty($coupon['limit_indate_begin']) && !empty($coupon['limit_indate_end'])) {
            if (time() < strtotime($coupon['limit_indate_begin']) || time() > strtotime($coupon['limit_indate_end'])) {
                $flag = false;
            }
        }

        if ($coupon['user_limit_type'] = 1) {
            $count = UserCoupon::where('user_id', $find['user_id'])
                ->where('coupon_id', $user_coupon['coupon_id'])
                ->count();

            if ($count >= $coupon['user_limit']) {
                $flag = false;
            }
        }

        if ($flag) {
            $user_coupon->unified_order_no = null;
            $user_coupon->status = 0;
            $user_coupon->save();
        }

    }

    private function sendMsg(int $oid, $msg)
    {
        $order = Order::with(['orderCommodity' => function (Query $query) {
            $query->alias('a')
                ->join('commodity c', 'a.commodity_id = c.id', 'LEFT')
                ->field('c.name,a.express_company,a.logistics_no,a.order_id');
        }])
            ->find($oid)
            ->toArray();
        $user = User::find($order['user_id']);

        if (empty($user)) return;
        $arr = [];
        $arr['str'] = '';
        $arr['express_name'] = '';
        $arr['logistics_no'] = '';
        foreach ($order['orderCommodity'] as $v) {
            $arr['str'] .= $v['name'] . "-";
            $arr['express_name'] .= $v['express_company'] . '-';
            $arr['logistics_no'] .= $v['logistics_no'] . '-';
        }
        foreach ($arr as $k => $v) {
            $arr[$k] = cut_str(trim($v, '-'), 10);
            if ($k == "express_name") {
                $arr[$k] = cut_str(trim($v, '-'), 4, false);
            }
        }
        $buyer_str = $order['consignee'] . "/" . $order['iphone'] . "/" . $order['address'];
        $buyer_info = strlen($buyer_str) > 150 ?
            cut_str($buyer_str, 10)
            : $buyer_str;
        $user_wx = UserWx::where('user_id', $order['user_id'])->find();
        if (!empty($user_wx)) {
            $url = $user_wx['type'] == 1 ? "/orderpage/order/orderdetail?type=4&id=" . $order['id']."&mall_id=". $order["mall_id"] : Request::domain() . "/h5/#/orderpage/order/orderdetail?type=4&id=" . $order['id']."&mall_id=". $order["mall_id"];
            switch ($msg) {
                case "订单发货通知":
                    $data = [
                        "mall_name" => MallBase::getBase(),
                        "commodity_name" => $arr['str'],
                        "order_no" => $order['order_no'],
                        'express_name' => $arr['express_name'],
                        "express_no" => $arr['logistics_no'],
                        "buyer_info" => $buyer_info,
                        "order_create_time" => $order['create_time'],
                        "order_sell_time" => date("Y-m-d H:i:s", time()),
                        "buyer_mobile" => $order['iphone'],
                        "thing4" => $order['order_no']
                    ];
                    break;
                case "订单支付通知":
                    $data = [
                        "commodity_name" => $arr['str'],
                        "order_cash" => $order['money'],
                        "order_no" => $order['order_no'],
                        "order_create_time" => $order['create_time'],
                        "thing4" => " "
                    ];
                    break;
                case "订单手动退款通知":
                    $data = [
                        "commodity_refund_name" => $arr['str'],
                        "refund_cash" => $order['money'],
                        "order_create_time" => $order['create_time'],
                        "order_no" => $order['order_no'],
                    ];
            }
            $data['buyer_mobile'] = $order['iphone'];
            $sendMsg = new SendMsg($msg);
            if ($user_wx['type'] == 1) {
                $data['character_string1'] = $order['order_no'];
                $data['thing2'] = $arr['str'];
                $data['phrase3'] = $arr['express_name'];
                $data['character_string4'] = $arr['logistics_no'];
                $data['date5'] = date("Y-m-d H:i:s", time());
                $data['amount2'] = $order['money'];
                $data['date3'] = date("Y-m-d H:i:s", time());
            }
            $sendMsg->send($user, $data, $url);
        }
    }

    /**下载文件
     * @param string $filename
     * @param string $name
     */
    public function download_file(string $filename, string $name)
    {
        Header("Content-type:  application/octet-stream ");
        Header("Accept-Ranges:  bytes ");
        Header("Accept-Length: " . filesize($filename));
        header("Content-Disposition:  attachment;  filename= {$name}.xls");
        echo file_get_contents($filename);
        readfile($filename);
    }
}